package com.yalantis.taurus.library;


import ohos.aafwk.ability.Ability;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.*;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;


/**
 * Created by cuneytcarikci on 17/08/2017.
 */

public class ContinuousScrollableImageView extends DirectionalLayout {

    public static final String TAG = ContinuousScrollableImageView.class.getSimpleName();

    HiLogLabel label=new HiLogLabel(HiLog.LOG_APP,0,TAG);

    //方向
    //<editor-fold desc="DEFAULT_DIRECTION = LEFT">
    public static final int UP = 0;
    public static final int RIGHT = 1;
    public static final int DOWN = 2;
    public static final int LEFT = 3;



    @Retention(RetentionPolicy.SOURCE)
    @interface Directions {
    }

    @Directions
    int DEFAULT_DIRECTION = LEFT;
    //</editor-fold>


    //<editor-fold desc="DEFAULT_ASYMPTOTE = HORIZONTAL">
    public static final int HORIZONTAL = 0;
    public static final int VERTICAL = 1;

    @Retention(RetentionPolicy.SOURCE)
    @interface Asymptote {
    }

    @Asymptote
    int DEFAULT_ASYMPTOTE = HORIZONTAL;
    //</editor-fold>


    //<editor-fold desc="DEFAULT_SCALE_TYPE = CENTER">
//    public static final int MATRIX = 0;

    public static final int FIT_XY = 1;

    public static final int FIT_START = 2;

    public static final int FIT_CENTER = 3;

    public static final int FIT_END = 4;

    public static final int CENTER = 5;

    public static final int CENTER_CROP = 6;

    public static final int CENTER_INSIDE = 7;


    @Retention(RetentionPolicy.SOURCE)
    @interface ScaleType {
    }

    @ScaleType
    int DEFAULT_SCALE_TYPE = FIT_CENTER;
    //</editor-fold>

    private final int DEFAULT_RESOURCE_ID = -1;
    private final int DEFAULT_DURATION = 3000;
    private int DIRECTION_MULTIPLIER = -1;

    private int duration;
    private int resourceId;
    private int direction;
    private int scaleType;

    private AnimatorValue animator;
    private Image firstImage;
    private Image secondImage;

    private boolean isBuilt = false;



    /*
     * 构造函数
     */
    public ContinuousScrollableImageView(Context context) {
        super(context);
        init(context);
    }

    public ContinuousScrollableImageView(Context context, AttrSet attrs) {
        this(context, attrs, null);
    }

    public ContinuousScrollableImageView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
//        setViewAttributes(context, attrs, defStyleAttr);
        init(context);

    }

//    private void setViewAttributes(Context context, AttrSet attrs, String defStyleAttr) {
//        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ContinuousScrollableImage, defStyleAttr, 0);
//        resourceId = array.getResourceId(R.styleable.ContinuousScrollableImage_imageSrc, DEFAULT_RESOURCE_ID);
//        direction = array.getInt(R.styleable.ContinuousScrollableImage_direction, DEFAULT_DIRECTION);
//        duration = array.getInt(R.styleable.ContinuousScrollableImage_duration, DEFAULT_DURATION);
//        scaleType = array.getInt(R.styleable.ContinuousScrollableImage_scaleType, DEFAULT_SCALE_TYPE);
//        setDirectionFlags(direction);
//        array.recycle();
//    }

    /*
     * 通过输入的方向来更改DIRECTION_MULTIPLIER和DEFAULT_ASYMPTOTE
     */
    private void setDirectionFlags(int direction) {
        switch (direction) {
            case UP:
                DIRECTION_MULTIPLIER = 1;
                DEFAULT_ASYMPTOTE = VERTICAL;
                break;
            case RIGHT:
                DIRECTION_MULTIPLIER = -1;
                DEFAULT_ASYMPTOTE = HORIZONTAL;
                break;
            case DOWN:
                DIRECTION_MULTIPLIER = -1;
                DEFAULT_ASYMPTOTE = VERTICAL;
                break;
            case LEFT:
                DIRECTION_MULTIPLIER = 1;
                DEFAULT_ASYMPTOTE = HORIZONTAL;
                break;
        }
    }

    /**
     * @param context
     */
    private void init(Context context) {
        LayoutScatter.getInstance(context).parse( ResourceTable.Layout_continuos_scrollable_imageview_layout, this,true);
        build();
        setBindStateChangedListener(bindStateChangedListener);
    }


    /**
     * Set duration in ms
     *
     * @param duration
     */

    public void setDuration(int duration) {
        this.duration = duration;
        isBuilt = false;
        build();
    }


    /**
     * set scrolling direction
     *
     * @param direction
     */

    public void setDirection(@Directions int direction) {
        this.direction = direction;
        isBuilt = false;
        setDirectionFlags(direction);
        build();
    }

    /**
     * @param resourceId
     */

    public void setResourceId(int resourceId) {
        this.resourceId = resourceId;
        firstImage.setImageAndDecodeBounds(this.resourceId);
        secondImage.setImageAndDecodeBounds(this.resourceId);
    }


    /**
     * set image scale type
     *
     * @param scaleType
     */
    public void setScaleType(@ScaleType int scaleType) {
        if (firstImage == null || secondImage == null) {
            throw new NullPointerException();
        }
        Image.ScaleMode type = Image.ScaleMode.CENTER;
        switch (scaleType) {

//            case MATRIX:
//                type = Image.ScaleMode.MATRIX;
//                break;

            case FIT_XY:
                type = Image.ScaleMode.STRETCH;
                break;

            case FIT_START:
                type = Image.ScaleMode.ZOOM_START;
                break;

            case FIT_CENTER:
                type = Image.ScaleMode.ZOOM_CENTER;
                break;

            case FIT_END:
                type = Image.ScaleMode.ZOOM_END;
                break;

            case CENTER:
                type = Image.ScaleMode.CENTER;
                break;

            case CENTER_CROP:
                type = Image.ScaleMode.CLIP_CENTER;
                break;

            case CENTER_INSIDE:
                type = Image.ScaleMode.INSIDE;
                break;

        }
        this.scaleType = scaleType;
        firstImage.setScaleMode(type);
        secondImage.setScaleMode(type);
    }

    /*
     * 图像的滚动效果
     */
    private void build() {
        if (isBuilt)
            return;

        isBuilt = true;
        setImages();

        if (animator != null)
            animator.release();

        animator = new AnimatorValue();
        animator.setLoopedCount(AnimatorValue.INFINITE);
        animator.setCurveType(Animator.CurveType.LINEAR);
        animator.setDuration(duration);
        switch (DEFAULT_ASYMPTOTE) {
            case HORIZONTAL:
                animator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
                    @Override
                    public void onUpdate(AnimatorValue animatorValue, float v) {
                        float progress;
                        if (DIRECTION_MULTIPLIER==1)
                            progress = DIRECTION_MULTIPLIER * ( v);
                        else
                            progress =  DIRECTION_MULTIPLIER * ( - v);
                        float width = DIRECTION_MULTIPLIER * (-firstImage.getWidth());
                        float translationX = width * progress;
                        firstImage.setTranslationX(translationX);
                        secondImage.setTranslationX(translationX - width);
                    }
                });
                break;

            case VERTICAL:
                animator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
                    @Override
                    public void onUpdate(AnimatorValue animatorValue, float v) {
                        float progress;
                        if (DIRECTION_MULTIPLIER==1)
                            progress = DIRECTION_MULTIPLIER * ( v);
                        else
                            progress =  DIRECTION_MULTIPLIER * ( - v);
                        float height = DIRECTION_MULTIPLIER * (-firstImage.getHeight());
                        float translationY = height * progress;
                        firstImage.setTranslationY(translationY);
                        secondImage.setTranslationY(translationY - height);
                    }
                });
                break;
        }

//        animator.start();

    }

    public void setViewStart() {
        if (animator != null){
            animator.start();
        }
    }
    public void setViewStop() {
        if (animator != null){
            animator.stop();
        }
    }
    /*
     * set images
     */
    private void setImages() {
        if (resourceId == -1) {
            HiLog.error(label,"image must be initialized before it can be used. You can use in XML like this: (app:imageSrc=\"@drawable/yourImage\") ",TAG);
            return;
        }
        firstImage = (Image) this.findComponentById(ResourceTable.Id_first_image);
        secondImage = (Image) this.findComponentById(ResourceTable.Id_second_image);
        firstImage.setImageAndDecodeBounds(resourceId);
        secondImage.setImageAndDecodeBounds(resourceId);
        setScaleType(scaleType);

    }

    /*
     *  把Component绑定到Window上
     */
    BindStateChangedListener bindStateChangedListener=new BindStateChangedListener() {
        @Override
        public void onComponentBoundToWindow(Component component) {

        }

        @Override
        public void onComponentUnboundFromWindow(Component component) {
            if (animator != null)
                animator.cancel();
        }
    };

    /*
     * Builder方式设置属性
     */
    public static final class Builder {

        private ContinuousScrollableImageView scrollableImage;

        public Builder(Ability ability) {
            scrollableImage = new ContinuousScrollableImageView(ability);
        }

        public Builder setDuration(int duration) {
            scrollableImage.setDuration(duration);
            return this;
        }

        public Builder setResourceId(int resourceId) {
            scrollableImage.setResourceId(resourceId);
            return this;
        }

        public Builder setDirection(@Directions int direction) {
            scrollableImage.setDirection(direction);
            return this;
        }

        public Builder setScaleType(@ScaleType int scaleType) {
            scrollableImage.setScaleType(scaleType);
            return this;
        }

        public ContinuousScrollableImageView build() {

            return scrollableImage;
        }
    }
}
